#include "fs_db.h"
#include "file_utils.h"
#include "sqlite3.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <dirent.h>

// 错误处理宏
#define DB_ERROR(rc, db, msg)                                 \
    if (rc != SQLITE_OK)                                      \
    {                                                         \
        fprintf(stderr, "%s: %s\n", msg, sqlite3_errmsg(db)); \
        return rc;                                            \
    }

// 内部函数声明
static int get_parent_path(const char *path, char *parent_path, size_t size);
static int add_to_directory_closure(sqlite3 *db, int node_id);
static int remove_from_directory_closure(sqlite3 *db, int node_id);

// fs_db.c
sqlite3 *fs_db_init()
{
    sqlite3 *db;
    char *err_msg = 0;

    // 确保db目录存在
    char db_dir[MAX_PATH_LEN];
    snprintf(db_dir, sizeof(db_dir), "%s/db", WORKSPACE_PATH);
    create_directory_recursive(db_dir);

    // 打开数据库
    int rc = sqlite3_open(DB_PATH, &db);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return NULL;
    }

    // 启用外键约束
    rc = sqlite3_exec(db, "PRAGMA foreign_keys = ON;", 0, 0, &err_msg);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "启用外键失败: %s\n", err_msg);
        sqlite3_free(err_msg);
    }

    // 创建表结构
    const char *create_tables[] = {
        // 用户表
        "CREATE TABLE IF NOT EXISTS users ("
        "id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "username TEXT UNIQUE NOT NULL,"
        "email TEXT UNIQUE,"
        "password_hash TEXT NOT NULL,"
        "status INTEGER DEFAULT 1,"
        "created_at INTEGER DEFAULT (strftime('%s','now')),"
        "last_login INTEGER,"
        "storage_quota INTEGER DEFAULT 1073741824"
        ");",

        // 文件系统节点表
        "CREATE TABLE IF NOT EXISTS fs_nodes ("
        "id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "path TEXT NOT NULL UNIQUE,"
        "name TEXT NOT NULL,"
        "owner_id INTEGER NOT NULL,"
        "is_directory BOOLEAN NOT NULL,"
        "is_public BOOLEAN DEFAULT 0,"
        "size INTEGER DEFAULT 0,"
        "last_modified INTEGER,"
        "last_accessed INTEGER,"
        "created_at INTEGER DEFAULT (strftime('%s','now')),"
        "checksum TEXT,"
        "parent_id INTEGER,"
        "marked_for_deletion INTEGER DEFAULT 0,"
        "deletion_scheduled INTEGER,"
        "FOREIGN KEY (owner_id) REFERENCES users(id),"
        "FOREIGN KEY (parent_id) REFERENCES fs_nodes(id)"
        ");",

        // 目录闭包表
        "CREATE TABLE IF NOT EXISTS directory_closure ("
        "ancestor INTEGER NOT NULL,"
        "descendant INTEGER NOT NULL,"
        "depth INTEGER NOT NULL,"
        "PRIMARY KEY (ancestor, descendant),"
        "FOREIGN KEY (ancestor) REFERENCES fs_nodes(id),"
        "FOREIGN KEY (descendant) REFERENCES fs_nodes(id)"
        ");",

        // 文件共享表
        "CREATE TABLE IF NOT EXISTS file_shares ("
        "id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "file_id INTEGER NOT NULL,"
        "user_id INTEGER NOT NULL,"
        "permission INTEGER DEFAULT 1,"
        "shared_by INTEGER NOT NULL,"
        "created_at INTEGER DEFAULT (strftime('%s','now')),"
        "FOREIGN KEY (file_id) REFERENCES fs_nodes(id),"
        "FOREIGN KEY (user_id) REFERENCES users(id),"
        "FOREIGN KEY (shared_by) REFERENCES users(id)"
        ");",

        // 回收站表
        "CREATE TABLE IF NOT EXISTS recycle_bin ("
        "id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "original_id INTEGER NOT NULL,"
        "path TEXT NOT NULL,"
        "name TEXT NOT NULL,"
        "owner_id INTEGER NOT NULL,"
        "deleted_at INTEGER DEFAULT (strftime('%s','now')),"
        "expire_at INTEGER,"
        "restore_path TEXT,"
        "FOREIGN KEY (original_id) REFERENCES fs_nodes(id),"
        "FOREIGN KEY (owner_id) REFERENCES users(id)"
        ");",

        // 公共文件管理表
        "CREATE TABLE IF NOT EXISTS public_files ("
        "file_id INTEGER PRIMARY KEY,"
        "download_count INTEGER DEFAULT 0,"
        "last_downloaded INTEGER,"
        "like_count INTEGER DEFAULT 0,"
        "FOREIGN KEY (file_id) REFERENCES fs_nodes(id)"
        ");",

        // 系统设置表
        "CREATE TABLE IF NOT EXISTS system_settings ("
        "id INTEGER PRIMARY KEY DEFAULT 1 CHECK (id = 1),"
        "public_dir_path TEXT DEFAULT '/public',"
        "default_storage_quota INTEGER DEFAULT 1073741824,"
        "max_public_file_size INTEGER DEFAULT 104857600,"
        "recycle_bin_retention INTEGER DEFAULT 2592000,"
        "user_deletion_delay INTEGER DEFAULT 86400"
        ");"};

    // 执行表创建
    for (size_t i = 0; i < sizeof(create_tables) / sizeof(create_tables[0]); i++)
    {
        rc = sqlite3_exec(db, create_tables[i], 0, 0, &err_msg);
        if (rc != SQLITE_OK)
        {
            fprintf(stderr, "创建表失败: %s\n", err_msg);
            sqlite3_free(err_msg);
        }
    }

    // ======== 系统初始化 ========

    // 创建系统用户 (id=0)
    rc = sqlite3_exec(db,
                      "INSERT OR IGNORE INTO users (id, username, email, password_hash) "
                      "VALUES (0, 'system', 'system@example.com', 'system_password')",
                      0, 0, &err_msg);
    if (rc != SQLITE_OK && err_msg)
    {
        fprintf(stderr, "创建系统用户失败: %s\n", err_msg);
        sqlite3_free(err_msg);
    }

    // 初始化系统设置
    rc = sqlite3_exec(db,
                      "INSERT OR IGNORE INTO system_settings (id, public_dir_path) VALUES (1, '/public');",
                      0, 0, &err_msg);
    if (rc != SQLITE_OK && err_msg)
    {
        fprintf(stderr, "初始化设置失败: %s\n", err_msg);
        sqlite3_free(err_msg);
    }

    // 创建根目录（owner_id=0）
    rc = sqlite3_exec(db,
                      "INSERT OR IGNORE INTO fs_nodes "
                      "(path, name, owner_id, is_directory, created_at) VALUES "
                      "('/', 'root', 0, 1, strftime('%s','now'))",
                      0, 0, &err_msg);
    if (rc != SQLITE_OK && err_msg)
    {
        fprintf(stderr, "创建根目录失败: %s\n", err_msg);
        sqlite3_free(err_msg);
    }

    // 创建公共目录（owner_id=0）
    rc = sqlite3_exec(db,
                      "INSERT OR IGNORE INTO fs_nodes "
                      "(path, name, owner_id, is_directory, created_at) VALUES "
                      "('/public', 'public', 0, 1, strftime('%s','now'))",
                      0, 0, &err_msg);
    if (rc != SQLITE_OK && err_msg)
    {
        fprintf(stderr, "创建公共目录失败: %s\n", err_msg);
        sqlite3_free(err_msg);
    }

    return db;
}

// 关闭数据库
void fs_db_close(sqlite3 *db)
{
    sqlite3_close(db);
}

// 创建用户
int fs_create_user(sqlite3 *db, const char *username, const char *email, const char *password_hash)
{
    // 检查用户是否存在
    if (fs_user_exists(db, username))
    {
        fprintf(stderr, "用户 %s 已存在\n", username);
        return -1;
    }

    // 创建用户目录
    char user_dir[MAX_PATH_LEN];
    snprintf(user_dir, sizeof(user_dir), "%s/%s", WORKSPACE_PATH, username);
    printf("成功创建用户目录:%s\n", user_dir);
    if (!create_directory_recursive(user_dir))
    {
        fprintf(stderr, "无法创建用户目录: %s\n", user_dir);
        return -1;
    }

    // 添加用户到数据库
    sqlite3_stmt *stmt;
    const char *sql = "INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备插入用户失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, email, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 3, password_hash, -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "插入用户失败: %s\n", sqlite3_errmsg(db));
        sqlite3_finalize(stmt);
        return -1;
    }

    sqlite3_finalize(stmt);
    return sqlite3_last_insert_rowid(db);
}

// 删除用户
int fs_delete_user(sqlite3 *db, const char *username)
{
    int user_id = fs_get_user_id(db, username);
    if (user_id == -1)
    {
        fprintf(stderr, "用户 %s 不存在\n", username);
        return -1;
    }

    // 标记用户为已删除
    sqlite3_stmt *stmt;
    const char *sql = "UPDATE users SET status = 0 WHERE username = ?";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备删除用户失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "删除用户失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    // 删除用户目录
    char user_dir[MAX_PATH_LEN];
    snprintf(user_dir, sizeof(user_dir), "%s/%s", WORKSPACE_PATH, username);
    if (!delete_directory_recursive(user_dir))
    {
        fprintf(stderr, "警告: 无法完全删除用户目录 %s\n", user_dir);
    }

    // 标记用户文件为待删除
    sql = "UPDATE fs_nodes SET marked_for_deletion = 1, deletion_scheduled = ? WHERE owner_id = ?";
    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备标记用户文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    time_t delete_time = time(NULL) + 86400; // 24小时后删除
    sqlite3_bind_int64(stmt, 1, delete_time);
    sqlite3_bind_int(stmt, 2, user_id);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "标记用户文件失败: %s\n", sqlite3_errmsg(db));
    }

    return 0;
}

// 获取用户ID
int fs_get_user_id(sqlite3 *db, const char *username)
{
    sqlite3_stmt *stmt;
    const char *sql = "SELECT id FROM users WHERE username = ?";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备获取用户ID失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);

    int user_id = -1;
    if (sqlite3_step(stmt) == SQLITE_ROW)
    {
        user_id = sqlite3_column_int(stmt, 0);
    }

    sqlite3_finalize(stmt);
    return user_id;
}

// 检查用户是否存在
bool fs_user_exists(sqlite3 *db, const char *username)
{
    return fs_get_user_id(db, username) != -1;
}

// 获取父目录路径
static int get_parent_path(const char *path, char *parent_path, size_t size)
{
    if (path == NULL || parent_path == NULL || size == 0)
    {
        return -1;
    }

    const char *last_slash = strrchr(path, '/');
    if (last_slash == NULL || last_slash == path)
    {
        // 根目录
        strncpy(parent_path, "/", size);
        return 0;
    }

    size_t parent_len = last_slash - path;
    if (parent_len >= size)
    {
        return -1;
    }

    strncpy(parent_path, path, parent_len);
    parent_path[parent_len] = '\0';
    return 0;
}

// 创建目录
int fs_create_directory(sqlite3 *db, const char *path, const char *name, int owner_id)
{
    // 创建物理目录
    char full_path[MAX_PATH_LEN];
    snprintf(full_path, sizeof(full_path), "%s/%s", WORKSPACE_PATH, path);

    if (!create_directory_recursive(full_path))
    {
        fprintf(stderr, "无法创建物理目录: %s\n", full_path);
        return -1;
    }

    // 获取父目录ID
    char parent_path[MAX_PATH_LEN];
    if (get_parent_path(path, parent_path, sizeof(parent_path)))
    {
        fprintf(stderr, "无法获取父目录路径: %s\n", path);
        return -1;
    }

    int parent_id = fs_get_directory_id(db, parent_path);
    if (parent_id == -1 && strcmp(parent_path, "/") != 0)
    {
        fprintf(stderr, "父目录不存在: %s\n", parent_path);
        return -1;
    }

    // 添加到数据库
    sqlite3_stmt *stmt;
    const char *sql = "INSERT INTO fs_nodes (path, name, owner_id, is_directory, created_at, parent_id) "
                      "VALUES (?, ?, ?, 1, strftime('%s','now'), ?)";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备创建目录失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, name, -1, SQLITE_STATIC);
    sqlite3_bind_int(stmt, 3, owner_id);
    sqlite3_bind_int(stmt, 4, parent_id);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "创建目录失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    int dir_id = sqlite3_last_insert_rowid(db);

    // 添加到闭包表
    if (add_to_directory_closure(db, dir_id) != SQLITE_OK)
    {
        fprintf(stderr, "添加到闭包表失败\n");
    }

    return dir_id;
}

// 获取目录ID
int fs_get_directory_id(sqlite3 *db, const char *path)
{
    sqlite3_stmt *stmt;
    const char *sql = "SELECT id FROM fs_nodes WHERE path = ? AND is_directory = 1";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备获取目录ID失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);

    int dir_id = -1;
    if (sqlite3_step(stmt) == SQLITE_ROW)
    {
        dir_id = sqlite3_column_int(stmt, 0);
    }

    sqlite3_finalize(stmt);
    return dir_id;
}

// 获取父目录ID
int fs_get_parent_directory_id(sqlite3 *db, const char *path)
{
    char parent_path[MAX_PATH_LEN];
    if (get_parent_path(path, parent_path, sizeof(parent_path)))
    {
        return -1;
    }
    return fs_get_directory_id(db, parent_path);
}

// 检查目录是否存在
bool fs_directory_exists(sqlite3 *db, const char *path)
{
    return fs_get_directory_id(db, path) != -1;
}

// 添加文件
int fs_add_file(sqlite3 *db, const char *path, const char *name, int owner_id,
                long size, bool is_public, int parent_id)
{
    // 构建物理路径
    char physical_path[MAX_PATH_LEN];
    snprintf(physical_path, sizeof(physical_path), "%s/%s", WORKSPACE_PATH, path);

    // 检查文件是否存在
    struct stat st;
    if (stat(physical_path, &st) != 0)
    {
        fprintf(stderr, "物理文件不存在: %s\n", physical_path);
        return -1;
    }

    // 添加到数据库
    sqlite3_stmt *stmt;
    const char *sql = "INSERT INTO fs_nodes (path, name, owner_id, is_directory, "
                      "size, is_public, created_at, last_modified, parent_id) "
                      "VALUES (?, ?, ?, 0, ?, ?, strftime('%s','now'), ?, ?)";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备添加文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, name, -1, SQLITE_STATIC);
    sqlite3_bind_int(stmt, 3, owner_id);
    sqlite3_bind_int64(stmt, 4, size);
    sqlite3_bind_int(stmt, 5, is_public ? 1 : 0);
    sqlite3_bind_int64(stmt, 6, st.st_mtime);
    sqlite3_bind_int(stmt, 7, parent_id);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "添加文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    return sqlite3_last_insert_rowid(db);
}

// 更新文件信息
int fs_update_file(sqlite3 *db, const char *path, long new_size)
{
    sqlite3_stmt *stmt;
    const char *sql = "UPDATE fs_nodes SET size = ?, last_modified = ? WHERE path = ?";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备更新文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_int64(stmt, 1, new_size);
    sqlite3_bind_int64(stmt, 2, time(NULL));
    sqlite3_bind_text(stmt, 3, path, -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "更新文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    return sqlite3_changes(db);
}

// 移动文件到回收站
int fs_move_to_recycle_bin(sqlite3 *db, const char *file_path)
{
    sqlite3_stmt *stmt;
    const char *sql = "INSERT INTO recycle_bin (original_id, path, name, owner_id, restore_path) "
                      "SELECT id, path, name, owner_id, ? "
                      "FROM fs_nodes WHERE path = ?";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备移动文件到回收站失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    // 设置恢复路径为当前路径
    sqlite3_bind_text(stmt, 1, file_path, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, file_path, -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "移动文件到回收站失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    return 0;
}

// 删除文件
int fs_delete_file(sqlite3 *db, const char *path)
{
    // 移动到回收站
    int rc = fs_move_to_recycle_bin(db, path);
    if (rc != SQLITE_OK)
    {
        return rc;
    }

    // 删除数据库记录
    sqlite3_stmt *stmt;
    const char *sql = "DELETE FROM fs_nodes WHERE path = ?";

    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备删除文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "删除文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    // 删除物理文件
    char physical_path[MAX_PATH_LEN];
    snprintf(physical_path, sizeof(physical_path), "%s/%s", WORKSPACE_PATH, path);
    if (!delete_file_physical(physical_path))
    {
        fprintf(stderr, "警告: 无法删除物理文件 %s\n", physical_path);
    }

    return 0;
}

// 移动文件
int fs_move_file(sqlite3 *db, const char *old_path, const char *new_path)
{
    // 移动物理文件
    char old_physical_path[MAX_PATH_LEN];
    char new_physical_path[MAX_PATH_LEN];
    snprintf(old_physical_path, sizeof(old_physical_path), "%s/%s", WORKSPACE_PATH, old_path);
    snprintf(new_physical_path, sizeof(new_physical_path), "%s/%s", WORKSPACE_PATH, new_path);

    if (!move_file(old_physical_path, new_physical_path))
    {
        fprintf(stderr, "无法移动物理文件\n");
        return -1;
    }

    // 更新数据库
    sqlite3_stmt *stmt;
    const char *sql = "UPDATE fs_nodes SET path = ?, name = ? WHERE path = ?";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备移动文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    // 从新路径中提取文件名
    const char *name = strrchr(new_path, '/');
    if (name)
        name++;
    else
        name = new_path;

    sqlite3_bind_text(stmt, 1, new_path, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, name, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 3, old_path, -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "更新文件路径失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    return 0;
}

// 复制文件
int fs_copy_file(sqlite3 *db, const char *src_path, const char *dest_path)
{
    // 复制物理文件
    char src_physical_path[MAX_PATH_LEN];
    char dest_physical_path[MAX_PATH_LEN];
    snprintf(src_physical_path, sizeof(src_physical_path), "%s/%s", WORKSPACE_PATH, src_path);
    snprintf(dest_physical_path, sizeof(dest_physical_path), "%s/%s", WORKSPACE_PATH, dest_path);

    if (!copy_file(src_physical_path, dest_physical_path))
    {
        fprintf(stderr, "无法复制物理文件\n");
        return -1;
    }

    // 获取源文件信息
    sqlite3_stmt *stmt;
    const char *sql = "SELECT owner_id, size, is_public, parent_id FROM fs_nodes WHERE path = ?";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备获取文件信息失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_text(stmt, 1, src_path, -1, SQLITE_STATIC);

    int owner_id = -1;
    long size = 0;
    bool is_public = false;
    int parent_id = -1;

    if (sqlite3_step(stmt) == SQLITE_ROW)
    {
        owner_id = sqlite3_column_int(stmt, 0);
        size = sqlite3_column_int64(stmt, 1);
        is_public = sqlite3_column_int(stmt, 2) != 0;
        parent_id = sqlite3_column_int(stmt, 3);
    }
    sqlite3_finalize(stmt);

    if (owner_id == -1)
    {
        fprintf(stderr, "源文件不存在: %s\n", src_path);
        return -1;
    }

    // 从目标路径中提取文件名
    const char *name = strrchr(dest_path, '/');
    if (name)
        name++;
    else
        name = dest_path;

    // 添加新文件记录
    return fs_add_file(db, dest_path, name, owner_id, size, is_public, parent_id);
}

// 标记文件为公开
int fs_mark_file_public(sqlite3 *db, const char *path, bool is_public)
{
    sqlite3_stmt *stmt;
    const char *sql = "UPDATE fs_nodes SET is_public = ? WHERE path = ?";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备标记文件公开失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_int(stmt, 1, is_public ? 1 : 0);
    sqlite3_bind_text(stmt, 2, path, -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "标记文件公开失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    return sqlite3_changes(db);
}

// 同步文件信息
int fs_sync_file(sqlite3 *db, const char *file_path, int owner_id)
{
    char physical_path[MAX_PATH_LEN];
    snprintf(physical_path, sizeof(physical_path), "%s/%s", WORKSPACE_PATH, file_path);

    struct stat st;
    if (stat(physical_path, &st) != 0)
    {
        // 文件不存在，从数据库删除
        return fs_delete_file(db, file_path);
    }

    // 检查是否在数据库中
    sqlite3_stmt *stmt;
    const char *sql = "SELECT id, size FROM fs_nodes WHERE path = ?";
    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备检查文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_text(stmt, 1, file_path, -1, SQLITE_STATIC);

    int file_id = -1;
    long db_size = -1;

    if (sqlite3_step(stmt) == SQLITE_ROW)
    {
        file_id = sqlite3_column_int(stmt, 0);
        db_size = sqlite3_column_int64(stmt, 1);
    }
    sqlite3_finalize(stmt);

    if (file_id == -1)
    {
        // 文件不在数据库中，添加它
        char *name = strrchr(file_path, '/');
        if (name)
            name++;
        else
            name = (char *)file_path;

        int parent_id = fs_get_parent_directory_id(db, file_path);
        return fs_add_file(db, file_path, name, owner_id, st.st_size, false, parent_id);
    }

    if (db_size != st.st_size)
    {
        // 文件大小改变，更新数据库
        return fs_update_file(db, file_path, st.st_size);
    }

    return 0; // 文件已同步
}

// 扫描用户目录
int fs_scan_user_directory(sqlite3 *db, const char *username)
{
    int user_id = fs_get_user_id(db, username);
    if (user_id == -1)
    {
        fprintf(stderr, "用户 %s 不存在\n", username);
        return -1;
    }

    char user_dir[MAX_PATH_LEN];
    snprintf(user_dir, sizeof(user_dir), "%s/%s", WORKSPACE_PATH, username);

    DIR *dir = opendir(user_dir);
    if (!dir)
    {
        fprintf(stderr, "无法打开用户目录: %s\n", user_dir);
        return -1;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL)
    {
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
        {
            continue;
        }

        char file_path[MAX_PATH_LEN];
        snprintf(file_path, sizeof(file_path), "%s/%s", username, entry->d_name);

        char physical_path[MAX_PATH_LEN];
        snprintf(physical_path, sizeof(physical_path), "%s/%s", WORKSPACE_PATH, file_path);

        struct stat st;
        if (stat(physical_path, &st) != 0)
        {
            continue;
        }

        if (S_ISDIR(st.st_mode))
        {
            // 递归扫描子目录
            fs_scan_user_directory(db, file_path);
        }
        else
        {
            // 同步文件
            fs_sync_file(db, file_path, user_id);
        }
    }

    closedir(dir);
    return 0;
}

// 重建索引
int fs_rebuild_index(sqlite3 *db)
{
    // 删除所有文件记录
    sqlite3_exec(db, "DELETE FROM fs_nodes", 0, 0, 0);
    sqlite3_exec(db, "DELETE FROM directory_closure", 0, 0, 0);

    // 重新扫描所有用户目录
    sqlite3_stmt *stmt;
    const char *sql = "SELECT username FROM users";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备获取用户列表失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    while (sqlite3_step(stmt) == SQLITE_ROW)
    {
        const char *username = (const char *)sqlite3_column_text(stmt, 0);
        fs_scan_user_directory(db, username);
    }
    sqlite3_finalize(stmt);

    // 扫描公共目录
    fs_scan_user_directory(db, "public");

    // 扫描管理员目录
    fs_scan_user_directory(db, "admin");

    return 0;
}

// 列出用户文件
void fs_list_user_files(sqlite3 *db, int user_id)
{
    sqlite3_stmt *stmt;
    const char *sql =
        "SELECT id, path, name, size, "
        "datetime(last_modified, 'unixepoch') as modified, "
        "CASE WHEN is_directory THEN '目录' ELSE '文件' END as type "
        "FROM fs_nodes "
        "WHERE owner_id = ? AND marked_for_deletion = 0 "
        "ORDER BY path";

    printf("\n用户 %d 的文件列表:\n", user_id);
    printf("%-5s %-40s %-20s %-10s %-20s %-6s\n",
           "ID", "路径", "文件名", "大小", "修改时间", "类型");
    printf("-------------------------------------------------------------------------------\n");

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备列出文件失败: %s\n", sqlite3_errmsg(db));
        return;
    }

    sqlite3_bind_int(stmt, 1, user_id);

    while (sqlite3_step(stmt) == SQLITE_ROW)
    {
        int id = sqlite3_column_int(stmt, 0);
        const char *path = (const char *)sqlite3_column_text(stmt, 1);
        const char *name = (const char *)sqlite3_column_text(stmt, 2);
        long size = sqlite3_column_int64(stmt, 3);
        const char *modified = (const char *)sqlite3_column_text(stmt, 4);
        const char *type = (const char *)sqlite3_column_text(stmt, 5);

        printf("%-5d %-40s %-20s %-10ld %-20s %-6s\n",
               id, path, name, size, modified, type);
    }

    sqlite3_finalize(stmt);
    printf("\n");
}

// 列出目录内容
void fs_list_directory(sqlite3 *db, const char *dir_path)
{
    sqlite3_stmt *stmt;
    const char *sql =
        "SELECT id, name, size, "
        "datetime(last_modified, 'unixepoch') as modified, "
        "CASE WHEN is_directory THEN '目录' ELSE '文件' END as type "
        "FROM fs_nodes "
        "WHERE parent_id = (SELECT id FROM fs_nodes WHERE path = ?) "
        "AND marked_for_deletion = 0 "
        "ORDER BY name";

    printf("\n目录 %s 的内容:\n", dir_path);
    printf("%-5s %-20s %-10s %-20s %-6s\n",
           "ID", "文件名", "大小", "修改时间", "类型");
    printf("----------------------------------------------------------------\n");

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备列出目录失败: %s\n", sqlite3_errmsg(db));
        return;
    }

    sqlite3_bind_text(stmt, 1, dir_path, -1, SQLITE_STATIC);

    while (sqlite3_step(stmt) == SQLITE_ROW)
    {
        int id = sqlite3_column_int(stmt, 0);
        const char *name = (const char *)sqlite3_column_text(stmt, 1);
        long size = sqlite3_column_int64(stmt, 2);
        const char *modified = (const char *)sqlite3_column_text(stmt, 3);
        const char *type = (const char *)sqlite3_column_text(stmt, 4);

        printf("%-5d %-20s %-10ld %-20s %-6s\n",
               id, name, size, modified, type);
    }

    sqlite3_finalize(stmt);
    printf("\n");
}

// 搜索文件
void fs_search_files(sqlite3 *db, const char *username, const char *query)
{
    int user_id = fs_get_user_id(db, username);
    if (user_id == -1)
    {
        fprintf(stderr, "用户 %s 不存在\n", username);
        return;
    }

    sqlite3_stmt *stmt;
    const char *sql =
        "SELECT path, name, size, "
        "datetime(last_modified, 'unixepoch') as modified, "
        "CASE WHEN is_directory THEN '目录' ELSE '文件' END as type "
        "FROM fs_nodes "
        "WHERE owner_id = ? AND name LIKE ? AND marked_for_deletion = 0 "
        "ORDER BY path";

    printf("\n用户 %s 的文件搜索 (关键词: %s):\n", username, query);
    printf("%-40s %-20s %-10s %-20s %-6s\n",
           "路径", "文件名", "大小", "修改时间", "类型");
    printf("-------------------------------------------------------------------------------\n");

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备搜索文件失败: %s\n", sqlite3_errmsg(db));
        return;
    }

    sqlite3_bind_int(stmt, 1, user_id);

    // 添加通配符进行模糊搜索
    char pattern[MAX_NAME_LEN];
    snprintf(pattern, sizeof(pattern), "%%%s%%", query);
    sqlite3_bind_text(stmt, 2, pattern, -1, SQLITE_STATIC);

    while (sqlite3_step(stmt) == SQLITE_ROW)
    {
        const char *path = (const char *)sqlite3_column_text(stmt, 0);
        const char *name = (const char *)sqlite3_column_text(stmt, 1);
        long size = sqlite3_column_int64(stmt, 2);
        const char *modified = (const char *)sqlite3_column_text(stmt, 3);
        const char *type = (const char *)sqlite3_column_text(stmt, 4);

        printf("%-40s %-20s %-10ld %-20s %-6s\n",
               path, name, size, modified, type);
    }

    sqlite3_finalize(stmt);
    printf("\n");
}

// 添加到闭包表
static int add_to_directory_closure(sqlite3 *db, int node_id)
{
    // 插入自身关系 (深度0)
    sqlite3_stmt *stmt;
    const char *sql = "INSERT INTO directory_closure (ancestor, descendant, depth) "
                      "VALUES (?, ?, 0)";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备添加到闭包表失败: %s\n", sqlite3_errmsg(db));
        return rc;
    }

    sqlite3_bind_int(stmt, 1, node_id);
    sqlite3_bind_int(stmt, 2, node_id);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "添加到闭包表失败: %s\n", sqlite3_errmsg(db));
        return rc;
    }

    // 获取父目录ID
    sql = "SELECT parent_id FROM fs_nodes WHERE id = ?";
    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备获取父目录ID失败: %s\n", sqlite3_errmsg(db));
        return rc;
    }

    sqlite3_bind_int(stmt, 1, node_id);

    int parent_id = -1;
    if (sqlite3_step(stmt) == SQLITE_ROW)
    {
        parent_id = sqlite3_column_int(stmt, 0);
    }
    sqlite3_finalize(stmt);

    if (parent_id == -1)
    {
        return SQLITE_OK; // 根目录，没有父目录
    }

    // 插入父目录关系
    sql = "INSERT INTO directory_closure (ancestor, descendant, depth) "
          "SELECT ancestor, ?, depth + 1 "
          "FROM directory_closure "
          "WHERE descendant = ?";

    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备插入父目录关系失败: %s\n", sqlite3_errmsg(db));
        return rc;
    }

    sqlite3_bind_int(stmt, 1, node_id);
    sqlite3_bind_int(stmt, 2, parent_id);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "插入父目录关系失败: %s\n", sqlite3_errmsg(db));
    }

    return rc;
}

// 从闭包表移除
static int remove_from_directory_closure(sqlite3 *db, int node_id)
{
    sqlite3_stmt *stmt;
    const char *sql = "DELETE FROM directory_closure WHERE descendant = ?";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备从闭包表删除失败: %s\n", sqlite3_errmsg(db));
        return rc;
    }

    sqlite3_bind_int(stmt, 1, node_id);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "从闭包表删除失败: %s\n", sqlite3_errmsg(db));
    }

    return rc;
}

// 从回收站恢复
int fs_restore_from_recycle_bin(sqlite3 *db, int recycle_id)
{
    // 获取回收站项目信息
    sqlite3_stmt *stmt;
    const char *sql = "SELECT original_id, path, name, owner_id, restore_path "
                      "FROM recycle_bin WHERE id = ?";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备获取回收站项目失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_int(stmt, 1, recycle_id);

    int original_id = -1;
    const char *path = NULL;
    const char *name = NULL;
    int owner_id = -1;
    const char *restore_path = NULL;

    if (sqlite3_step(stmt) == SQLITE_ROW)
    {
        original_id = sqlite3_column_int(stmt, 0);
        path = (const char *)sqlite3_column_text(stmt, 1);
        name = (const char *)sqlite3_column_text(stmt, 2);
        owner_id = sqlite3_column_int(stmt, 3);
        restore_path = (const char *)sqlite3_column_text(stmt, 4);
    }
    sqlite3_finalize(stmt);

    if (original_id == -1)
    {
        fprintf(stderr, "回收站项目不存在\n");
        return -1;
    }

    // 恢复物理文件
    char physical_path[MAX_PATH_LEN];
    char restore_physical_path[MAX_PATH_LEN];
    snprintf(physical_path, sizeof(physical_path), "%s/%s", WORKSPACE_PATH, path);
    snprintf(restore_physical_path, sizeof(restore_physical_path), "%s/%s", WORKSPACE_PATH, restore_path);

    if (!move_file(physical_path, restore_physical_path))
    {
        fprintf(stderr, "恢复物理文件失败\n");
        return -1;
    }

    // 恢复数据库记录
    sql = "INSERT INTO fs_nodes (id, path, name, owner_id, is_directory, size, is_public, created_at, last_modified, parent_id) "
          "SELECT ?, ?, name, owner_id, is_directory, size, is_public, created_at, last_modified, parent_id "
          "FROM recycle_bin WHERE id = ?";

    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备恢复文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_int(stmt, 1, original_id);
    sqlite3_bind_text(stmt, 2, restore_path, -1, SQLITE_STATIC);
    sqlite3_bind_int(stmt, 3, recycle_id);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "恢复文件失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    // 从回收站删除
    sql = "DELETE FROM recycle_bin WHERE id = ?";
    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备从回收站删除失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    sqlite3_bind_int(stmt, 1, recycle_id);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    if (rc != SQLITE_DONE)
    {
        fprintf(stderr, "从回收站删除失败: %s\n", sqlite3_errmsg(db));
        return -1;
    }

    return 0;
}

// 清空回收站
void fs_empty_recycle_bin(sqlite3 *db)
{
    // 获取所有回收站项目
    sqlite3_stmt *stmt;
    const char *sql = "SELECT id, path FROM recycle_bin";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "准备获取回收站项目失败: %s\n", sqlite3_errmsg(db));
        return;
    }

    while (sqlite3_step(stmt) == SQLITE_ROW)
    {
        int id = sqlite3_column_int(stmt, 0);
        const char *path = (const char *)sqlite3_column_text(stmt, 1);

        // 删除物理文件
        char physical_path[MAX_PATH_LEN];
        snprintf(physical_path, sizeof(physical_path), "%s/%s", WORKSPACE_PATH, path);
        delete_file_physical(physical_path);
    }
    sqlite3_finalize(stmt);

    // 清空回收站表
    sqlite3_exec(db, "DELETE FROM recycle_bin", 0, 0, 0);
}